package unit5;

import java.awt.Dialog.ModalityType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

import javax.print.attribute.standard.Media;
import javax.swing.text.html.HTMLDocument.HTMLReader.SpecialAction;

public class Reflect {
	public static void main(String[] args) {
		String name;
		if(args.length>0)
			name=args[0];
		else
		{
			Scanner in=new Scanner(System.in);
			System.out.println("Enter class name(e.g. java.util.Date:");
			name=in.next();
		}
		try {
//			print class name and superclass name if(!=object)
			Class cl=Class.forName(name);
			Class supercl=cl.getSuperclass();
			String modifiers=Modifier.toString(cl.getModifiers());
			if(modifiers.length()>0)
				System.out.println(modifiers+"");
			System.out.println("class="+name);
			if(supercl!=null&&supercl!=Object.class)
				System.out.println("extends "+supercl.getName());
			System.out.print("\n{\n");
			printConstructors(cl);
			System.out.println();
			printMethod(cl);
			System.out.println();
			printField(cl);
			System.out.print("}");
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		System.exit(0);
	}

	private static void printField(Class cl) {
		// TODO Auto-generated method stub
		Field[] field=cl.getDeclaredFields();
		for(Field f:field){
			Class type=f.getType();
			String name=f.getName();
			System.out.println("    ");
			String modifiers=Modifier.toString(f.getModifiers());
			if(modifiers.length()>0)
				System.out.print(modifiers+"    ");
			System.out.println(type.getName()+"    "+name+";");
					
	}
	}
	@SuppressWarnings("unused")
	private static void printMethod(@SuppressWarnings("rawtypes") Class cl) {
		// TODO Auto-generated method stub
		Method[] methods=cl.getDeclaredMethods();
		for(Method m:methods){
			@SuppressWarnings({ "rawtypes" })
			Class retType=m.getReturnType();
			String name=m.getName();
			
			System.out.print("    ");
//			print modifiers ,return type and method name
			String 	modifiers=Modifier.toString(m.getModifiers());
			if(modifiers.length()>0)
				System.out.print(modifiers+"    ");
			
//			print parameter types
			@SuppressWarnings("rawtypes")
			Class[] paramTypes=m.getParameterTypes();
			for(int i=0;i<paramTypes.length;i++){
				if(i>0)
					System.out.print(",   ");
				System.out.print(paramTypes[i].getName());
			}
			System.out.println(");");
		}
		}
	private static void printConstructors(@SuppressWarnings("rawtypes") Class cl) {
		// TODO Auto-generated method stub
		@SuppressWarnings("rawtypes")
		Constructor[] constructors=cl.getDeclaredConstructors();
		for(Constructor<?> c:constructors){
			String name=c.getName();
			System.out.print("    ");
			String modifiers=Modifier.toString(c.getModifiers());
			if(modifiers.length()>0)
				System.out.print(modifiers+"    ");
			System.out.println(name+"(");
			
//			print parameter types
			@SuppressWarnings("rawtypes")
			Class[] paramTypes=c.getParameterTypes();
			for(int i=0;i<paramTypes.length;i++){
				if(i>0)
					System.out.print(",   ");
				System.out.print(paramTypes[i].getName());
			}
			System.out.println(");");
		}
		
	}
}
